home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- JuggleGraphics.c
-
- Routines that deal with drawing and GX objects
-
- ----------------------------------------------------------------------*/
-
- #include "PaperJuggling.h"
-
- //-----------------
- // Globals
- gxStyle gThrowStyle, gHandStyle, gLabelStyle;
- gxInk gThrowInk, gFadedThrowInk, gHandInk, gFadedHandInk, gLabelInk;
- gxViewDevice gTheMainDevice;
-
- //----------------------------------------------------
- // Initialization routine
-
- void InitCommonGraphicObjects(void)
- {
- gxViewDevice screenDevices[6]; // Plan for the most outrageous
- gxShape headShape;
- gxCapRecord capRec;
- gxColor bgColor, rsltColor;
- long numDevices,
- arrowGon[] = { 3, // 3 points
- ff(1), 0,
- -kArrowHeadLength, kArrowHeadHeight / 2,
- -kArrowHeadLength, -kArrowHeadHeight / 2};
-
- //-------------------------
- // Get the device we are tuning for
- // !!! This is cheesy, I should really make xor inks for each device and draw from DeviceLoop,
- // but my deadline is tomorrow. This means it will draw weird on other devices, and maybe even
- // crash! Oh, Boy!
- numDevices = GXGetViewGroupViewDevices(gxScreenViewDevices, screenDevices);
- gTheMainDevice = screenDevices[0];
-
- //-------------------------
- // Build the throw style
- gThrowStyle = GXNewStyle();
-
- // Make the arrow head shape
- headShape = NewPolygon((gxPolygon *) arrowGon);
-
- // Add arrow head as a line cap and dispose it
- capRec.startCap = nil;
- capRec.endCap = headShape;
- capRec.attributes = gxNoAttributes;
- GXSetStyleCap(gThrowStyle, &capRec);
- GXDisposeShape(headShape);
-
- // Set style pen
- GXSetStylePen(gThrowStyle, kArrowPenSize);
-
- // Set device grid attribute for clean lines
- GXSetStyleAttributes(gThrowStyle,
- GXGetStyleAttributes(gThrowStyle) | gxDeviceGridStyle);
-
- //-------------------------
- // Build the hand style
-
- gHandStyle = GXNewStyle();
-
- // Set the font & size
- SetStyleCommonFont(gHandStyle, genevaFont);
- GXSetStyleTextSize(gHandStyle, kHandTextSize);
-
- //-------------------------
- // Build the label style
-
- gLabelStyle = GXNewStyle();
-
- // Set the font, size, color, and hit test
- SetStyleCommonFont(gLabelStyle, genevaFont);
- GXSetStyleTextSize(gLabelStyle, kLabelTextSize);
-
- //-------------------------
- // Build the throw inks
-
- SetCommonColor(&bgColor, kBGColor);
-
- // make the throw ink
- gThrowInk = GXNewInk();
- SetCommonColor(&rsltColor, kArrowColor );
- SetInkFastXorTransfer(gThrowInk, gTheMainDevice, nil, &bgColor, &rsltColor);
-
- // make the faded throw ink and set to a 40% blend of the arrow color
- gFadedThrowInk = GXNewInk();
- SetInkBlendMode(gFadedThrowInk, 40);
- SetInkCommonColor(gFadedThrowInk, kArrowColor);
- // Get the resulting color when drawn on BGColor
- SetCommonColor(&rsltColor, kBGColor);
- GXCombineColor(&rsltColor, gFadedThrowInk);
- GXResetInk(gFadedThrowInk); // I don't know if this is really necessary, but what the hell
- SetInkFastXorTransfer(gFadedThrowInk, gTheMainDevice, nil, &bgColor, &rsltColor);
-
- //-------------------------
- // Build the hand inks
-
- // make the basic hand ink
- gHandInk = GXNewInk();
- SetInkCommonColor(gHandInk, kHandColor);
-
- // make the faded hand ink, a blend with the background
- gFadedHandInk = GXNewInk();
- SetInkBlendMode(gFadedHandInk, 40);
- SetInkCommonColor(gFadedHandInk, kHandColor);
- // Get the resulting color when drawn on BGColor
- SetCommonColor(&rsltColor, kBGColor);
- GXCombineColor(&rsltColor, gFadedHandInk);
- GXResetInk(gFadedHandInk); // I don't know if this is really necessary, but what the hell
- GXSetInkColor(gFadedHandInk, &rsltColor);
-
- // Build the label ink
- gLabelInk = GXNewInk();
- SetInkCommonColor(gLabelInk, kLabelColor);
- }
-
- void KillCommonGraphicObjects(void)
- {
- GXDisposeStyle(gThrowStyle);
- GXDisposeStyle(gHandStyle);
- GXDisposeStyle(gLabelStyle);
- GXDisposeInk(gThrowInk);
- GXDisposeInk(gFadedThrowInk);
- GXDisposeInk(gHandInk);
- GXDisposeInk(gFadedHandInk);
- GXDisposeInk(gLabelInk);
- }
-
- //----------------------------------------------------
- // shape creation routines
-
- // Make a new arrow to represent a throw, in the default position, perhaps faded
- gxShape MakeThrowShape(JuggleHandle aJuggle, Boolean faded)
- {
- gxShape newShape;
- gxLine lineData;
- Fixed hGrid = (*aJuggle)->gridPt.x;
-
- // Initialize the line geometry
- lineData.first.x = 0;
- lineData.first.y = 0;
- lineData.last.x = hGrid;
- lineData.last.y = 0;
-
- // Make the line shape
- newShape = GXNewLine(&lineData);
- NilShapeReturnNil(newShape);
-
- GXSetShapeHitTest(newShape, gxCornerPointPart + gxEdgePart + gxEndCapPart,
- kArrowPenSize);
-
- // Set its style and ink to our global ones
- GXSetShapeStyle(newShape, gThrowStyle);
- if(faded)
- {
- GXSetShapeInk(newShape, gFadedThrowInk);
- // Set shape to draw to the alternate view ports
- SetShapeFadePorts(aJuggle, newShape);
- }
- else
- {
- GXSetShapeInk(newShape, gThrowInk);
- SetShapeMainPort(aJuggle, newShape);
- }
-
- return newShape;
- }
-
- // Make a new text shape, L or R
- gxShape MakeHandShape(Boolean rightHand, Boolean faded)
- {
- gxShape newShape;
-
- // Make the text shape
- if(rightHand)
- newShape = GXNewText(1,(unsigned char*)"R", nil);
- else // This would have to change for three armed jugglers
- newShape = GXNewText(1,(unsigned char*)"L", nil);
- NilShapeReturnNil(newShape);
-
- // Set its style and ink to our global ones
- GXSetShapeStyle(newShape, gHandStyle);
- if(faded)
- {
- GXSetShapeInk(newShape, gFadedHandInk);
- }
- else
- {
- GXSetShapeInk(newShape, gHandInk);
- }
-
- // Hit test defaults to gxBoundsPart, 0 tolerance, which is fine
- return newShape;
- }
-
- // Make a new text shape containing "Juggler X" where X is the jugglerNumber
- // modified to just be the number
- gxShape MakeLabelShape(short jugglerNumber)
- {
- gxShape newShape;
- char numberText[50], labelText[50] = "Juggler ";
- short length;
-
- // Make the label string
- NumToString((long)jugglerNumber, (StringPtr)numberText);
- p2c((StringPtr)numberText);
- ccat(labelText, numberText);
- length = clen(labelText);
-
- // Make the text shape
- newShape = GXNewText(length, (unsigned char*)labelText, nil);
- NilShapeReturnNil(newShape);
-
- // Set its style and ink to our global ones
- GXSetShapeStyle(newShape, gLabelStyle);
- GXSetShapeInk(newShape, gLabelInk);
-
- // Hit test defaults to gxBoundsPart, 0 tolerance
- return newShape;
- }
-
- // Make a separator shape, a dashed line, in default position (under first row or
- // at the left)
- gxShape MakeSeparatorShape(JuggleHandle aJuggle, Boolean isHoriz)
- {
- gxShape newShape, dashShape;
- gxLine lineData;
- gxRectangle dashRect = {0, -fl(.5), ff(2), fl(.5)};
- gxDashRecord theDashRecord;
- gxPoint grid;
-
- grid = (*aJuggle)->gridPt;
-
- // Initialize the line geometry
- if(isHoriz)
- {
- lineData.first.x = 0;
- lineData.last.x = grid.x * ((*aJuggle)->numCounts - 1);
- lineData.first.y = lineData.last.y = grid.y / 2;
- }
- else
- {
- lineData.first.x = lineData.last.x = -(grid.x / 2);
- lineData.first.y = -(grid.y / 2);
- lineData.last.y = (grid.y * ((*aJuggle)->numJugglers - 1)) + (grid.y / 2);
- }
-
- // Make the line shape
- newShape = GXNewLine(&lineData);
- NilShapeReturnNil(newShape);
-
- // Make the dash shape
- dashShape = GXNewRectangle(&dashRect);
- NilShapeReturnNil(dashShape);
-
- // Add the dash and dispose it
- theDashRecord.attributes = gxAutoAdvanceDash;
- theDashRecord.dash = dashShape;
- theDashRecord.advance = ff(4);
- theDashRecord.phase = 0;
- theDashRecord.scale = ff(1);
- GXSetShapeDash(newShape, &theDashRecord);
- GXDisposeShape(dashShape);
-
- // Set the color, pen and hit test
- // SetShapeCommonColor(newShape, kSeparatorColor);
- GXSetShapePen(newShape, ff(1));
- if(isHoriz) // turn off hit testing for horizontal separators
- GXSetShapeHitTest(newShape, gxNoPart, ff(0));
-
- return newShape;
- }
-
- // Build a picture that is a row of Rs and Ls, in the default position (first row)
- gxShape MakeJugglerShape(JuggleHandle aJuggle, Boolean rightFirst, short jugglerNumber)
- {
- short numHandPairs, counter;
- Fixed twiceHGrid, repeatDist;
- gxShape labelShape, firstShape, secondShape, newPicture;
-
- // Make the new picture
- newPicture = GXNewShape(gxPictureType);
- NilShapeReturnNil(newPicture);
-
- // Set the unique items shape attribute so a new copy is made for each hand
- GXSetShapeAttributes(newPicture,
- GXGetShapeAttributes(newPicture) | gxUniqueItemsShape);
-
- // make and add the label shape
- labelShape = MakeLabelShape(jugglerNumber);
- NilShapeReturnNil(labelShape);
- MoveShapeCenterTo(labelShape, -(*aJuggle)->gridPt.x - ff(2), ff(0));
- AddToPicture(newPicture, labelShape, nil, nil, nil);
- GXDisposeShape(labelShape);
- labelShape = nil;
-
- // figure out the number of pairs of hands and the distance we need to move them
- numHandPairs = ((*aJuggle)->numCounts + 1) / 2;
- twiceHGrid = (*aJuggle)->gridPt.x * 2;
- repeatDist = (*aJuggle)->gridPt.x * (*aJuggle)->numCounts;
-
- // Make the solid hand shapes
- firstShape = MakeHandShape(rightFirst, false);
- NilShapeReturnNil(firstShape);
- MoveShapeCenterTo(firstShape, ff(0), ff(0));
- secondShape = MakeHandShape(!rightFirst, false);
- NilShapeReturnNil(secondShape);
- MoveShapeCenterTo(secondShape, (*aJuggle)->gridPt.x, ff(0));
-
- // Add the solid hand shapes, all in a row
- counter = numHandPairs;
- while(counter-- > 0)
- {
- AddToPicture(newPicture, firstShape, nil, nil, nil);
- GXMoveShape(firstShape, twiceHGrid, 0);
- AddToPicture(newPicture, secondShape, nil, nil, nil);
- GXMoveShape(secondShape, twiceHGrid, 0);
- }
-
- // Clean up
- GXDisposeShape(firstShape);
- GXDisposeShape(secondShape);
-
- // Make the faded hand shapes
- firstShape = MakeHandShape(rightFirst, true);
- NilShapeReturnNil(firstShape);
- MoveShapeCenterTo(firstShape, repeatDist, ff(0));
- secondShape = MakeHandShape(!rightFirst, true);
- NilShapeReturnNil(secondShape);
- MoveShapeCenterTo(secondShape, repeatDist + (*aJuggle)->gridPt.x, ff(0));
-
- // Add the faded hand shapes, all in a row
- counter = numHandPairs;
- while(counter-- > 0)
- {
- AddToPicture(newPicture, firstShape, nil, nil, nil);
- GXMoveShape(firstShape, twiceHGrid, 0);
- AddToPicture(newPicture, secondShape, nil, nil, nil);
- GXMoveShape(secondShape, twiceHGrid, 0);
- }
-
- // Clean up again
- GXDisposeShape(firstShape);
- GXDisposeShape(secondShape);
-
- return newPicture;
- }
-
- // Sets up a special shape for printing, with no weird colors or modes,
- // just black and white copy mode
- // !!! Should add in the faded throws, in gray, and print the title, too.
- gxShape MakePrintingShape(JuggleHandle aJuggle)
- {
- gxPoint grid;
- gxShape pageShape;
- gxInk defaultInk;
-
- // First make a copy of the shape
- pageShape = GXCopyDeepToShape(nil, (*aJuggle)->docPage);
- if(pageShape != nil)
- {
- // Move it over to account for the mapping offset of the content port
- //(We can't get it directly from the port, as it might be scrolled, and
- // scrolling changes the mapping)
- grid = (*aJuggle)->gridPt;
- GXMoveShape(pageShape, grid.x + (grid.x / 2), // 1 and a half times x
- grid.y / 2); // half of y
-
- // Set all shapes to draw in black, copy mode
- defaultInk = GXNewInk();
- SetDeepShapeInk(pageShape, defaultInk);
- GXDisposeInk(defaultInk);
-
- // Add in the faded throws
- }
- return pageShape;
- }
-
- // !!! Needs error checking
- OSErr SetUpJuggleViewPorts(WindowPtr window, JuggleHandle aJuggle)
- {
- gxViewPort docPort, newPort;
- gxViewGroup group;
- gxMapping portMapping;
- gxShape clipShape;
- gxRectangle clipRect;
- gxPoint grid = (*aJuggle)->gridPt;
-
- // Get the content port and set its mapping
- docPort = (*aJuggle)->docPort;
- GXGetViewPortMapping(docPort, &portMapping);
- MoveMapping(&portMapping,
- grid.x + (grid.x / 2), // 1 and a half times x
- grid.y / 2);
- GXSetViewPortMapping(docPort, &portMapping);
-
- // Set up rectangle to enclose the repeatable unit of the juggle
- // (in docPort space)
- clipRect.left = -(grid.x / 2);
- clipRect.top = -(grid.y / 2);
- clipRect.right = (grid.x * (*aJuggle)->numCounts) - (grid.x / 2);
- clipRect.bottom = ff(32000); // no clip on the bottom
- clipShape = GXNewRectangle(&clipRect);
-
- // Get the view group for the window
- group = GXGetViewPortViewGroup(docPort);
-
- // Make the before port and save in the juggle
- newPort = GXNewViewPort(group);
- GXSetViewPortClip(newPort, clipShape);
- ResetMapping(&portMapping);
- MoveMapping(&portMapping,
- -(grid.x * (*aJuggle)->numCounts), // shift left one juggle
- 0);
- GXSetViewPortMapping(newPort, &portMapping);
- GXSetViewPortParent(newPort, docPort);
- (*aJuggle)->beforePort = newPort;
-
- // Make the after port and save in the juggle
- newPort = GXNewViewPort(group);
- GXMoveShape(clipShape, grid.x * (*aJuggle)->numCounts, 0);
- GXSetViewPortClip(newPort, clipShape);
- ResetMapping(&portMapping);
- MoveMapping(&portMapping,
- grid.x * (*aJuggle)->numCounts, // shift right one juggle
- 0);
- GXSetViewPortMapping(newPort, &portMapping);
- GXSetViewPortParent(newPort, docPort);
- (*aJuggle)->afterPort = newPort;
-
- // Clean up
- GXDisposeShape(clipShape); clipShape = nil;
-
- return noErr;
- }
-
- // Make the picture shapes that contain the jugglers and throws. Add them
- // into one containing picture shape and return it. Also create the
- // arrow shape for the throws
- gxShape SetUpJuggleGraphics(WindowPtr window, JuggleHandle aJuggle)
- {
- gxShape pagePict, throwsPict, fadedThrowsPict, jugglersPict, sepsPict, juggler, sep;
- short count;
-
- //------------------------
- // Set up the view port hierarchy
- if(SetUpJuggleViewPorts(window, aJuggle) != noErr)
- return nil;
-
- //------------------------
- // make the jugglers pict
- jugglersPict = GXNewShape(gxPictureType);
- NilShapeReturnNil(jugglersPict);
-
- // Make it draw in the main port
- SetShapeMainPort(aJuggle, jugglersPict);
-
- // add the right number of jugglers
- for(count = 0; count < (*aJuggle)->numJugglers; count++)
- {
- juggler = MakeJugglerShape(aJuggle, true, count + 1);
- if(count > 0) // prevents warning: geometry_unnaffected
- GXMoveShape(juggler, 0, (*aJuggle)->gridPt.y * count);
- AddToPicture(jugglersPict, juggler, nil, nil, nil);
- GXDisposeShape(juggler);
- }
-
- //------------------------
- // make the throws pict
- throwsPict = GXNewShape(gxPictureType);
- NilShapeReturnNil(throwsPict);
-
- // Make it draw in the main port
- SetShapeMainPort(aJuggle, throwsPict);
-
- //------------------------
- // make the faded throws pict
- fadedThrowsPict = GXNewShape(gxPictureType);
- NilShapeReturnNil(fadedThrowsPict);
-
- // Set shape to draw to the alternate view ports
- SetShapeFadePorts(aJuggle, fadedThrowsPict);
-
- //------------------------
- // make the separators pict
- sepsPict = GXNewShape(gxPictureType);
- NilShapeReturnNil(sepsPict);
-
- // Make it draw in the main port
- SetShapeMainPort(aJuggle, sepsPict);
-
- GXSetShapeAttributes(sepsPict,
- GXGetShapeAttributes(sepsPict) | gxUniqueItemsShape);
-
- // Make one vertical separator
- sep = MakeSeparatorShape(aJuggle, false);
- NilShapeReturnNil(sep);
-
- // add it thrice, once at each end of the juggle, and once in the middle
- AddToPicture(sepsPict, sep, nil, nil, nil);
- GXMoveShape(sep, (*aJuggle)->numCounts * (*aJuggle)->gridPt.y, 0);
- AddToPicture(sepsPict, sep, nil, nil, nil);
- GXMoveShape(sep, (*aJuggle)->numCounts * (*aJuggle)->gridPt.y, 0);
- AddToPicture(sepsPict, sep, nil, nil, nil);
- GXDisposeShape(sep); sep = nil;
-
- // Make one horizontal separator
- sep = MakeSeparatorShape(aJuggle, true);
- NilShapeReturnNil(sep);
-
- // add the right number of horiz. separators and dispose the original
- count = (*aJuggle)->numJugglers - 1;
- while(count-- > 0)
- {
- AddToPicture(sepsPict, sep, nil, nil, nil);
- GXMoveShape(sep, 0, (*aJuggle)->gridPt.y);
- }
- GXDisposeShape(sep); sep = nil;
-
- //------------------------
- // get the page pict
- pagePict = (*aJuggle)->docPage;
-
- // Add the other pictures to the page pict
- AddToPicture(pagePict, jugglersPict, nil, nil, nil);
- AddToPicture(pagePict, sepsPict, nil, nil, nil);
- AddToPicture(pagePict, throwsPict, nil, nil, nil);
-
- // Save the appropriate references in the juggle structure
- (*aJuggle)->jugglersPict = jugglersPict;
- (*aJuggle)->throwsPict = throwsPict;
- (*aJuggle)->fadedThrowsPict = fadedThrowsPict;
- (*aJuggle)->sepsPict = sepsPict;
-
- // return the top level page pict
- return pagePict;
- }
-
- void CleanUpJuggleShapes(WindowPtr window)
- {
- JuggleHandle aJuggle = GetWindowJuggle(window);
-
- GXDisposeShape((*aJuggle)->jugglersPict); // Dispose of this doc's jugglers picture.
- GXDisposeShape((*aJuggle)->throwsPict); // Dispose of this doc's throws picture.
- GXDisposeShape((*aJuggle)->fadedThrowsPict); // Dispose of this doc's faded throws picture.
- GXDisposeShape((*aJuggle)->sepsPict); // Dispose of this doc's separators picture.
- }
-
- //----------------------------------------------------
- // graphics utility routines
-
- // Add the throw shape(s) to the throws pict(s), drawing it(them)
- void AddNewThrowShape(JuggleHandle aJuggle, gxLine *line, Boolean draw)
- {
- gxShape arrow, fadeArrow;
-
- // Make an arrow shape and set its geometry
- arrow = MakeThrowShape(aJuggle, false);
- GXSetLine(arrow, line);
-
- // Make a faded arrow shape and set its geometry
- fadeArrow = MakeThrowShape(aJuggle, true);
- GXSetLine(fadeArrow, line);
-
- // add them to the front of their pictures
- GXSetPictureParts((*aJuggle)->throwsPict, 1, 0, 1, &arrow, nil, nil, nil);
- GXSetPictureParts((*aJuggle)->fadedThrowsPict, 1, 0, 1, &fadeArrow, nil, nil, nil);
-
- // Draw them
- if(draw)
- {
- GXDrawShape(arrow);
- GXDrawShape(fadeArrow);
- }
-
- // clean up
- GXDisposeShape(arrow);
- GXDisposeShape(fadeArrow);
- }
-
- // Remove the throw shape from the throws pict, erasing first
- void RemoveThrowShape(JuggleHandle aJuggle, short shapeIndex)
- {
- gxShape throwShape, fadedThrowShape;
-
- // Get shapes
- GetPictureItem((*aJuggle)->throwsPict, shapeIndex, &throwShape, nil, nil, nil);
- GetPictureItem((*aJuggle)->fadedThrowsPict, shapeIndex, &fadedThrowShape, nil, nil, nil);
-
- // Erase them by drawing (xor, remember)
- GXDrawShape(throwShape);
- GXDrawShape(fadedThrowShape);
-
- // Remove shapes from throwsPict
- GXSetPictureParts((*aJuggle)->throwsPict, shapeIndex, 1, 0, nil, nil, nil, nil);
- GXSetPictureParts((*aJuggle)->fadedThrowsPict, shapeIndex, 1, 0, nil, nil, nil, nil);
- }
-
- // Change a throw shape, erasing the old and drawing the new
- void MoveThrowShape(JuggleHandle aJuggle, short shapeIndex, gxLine *newLine)
- {
- gxShape throwShape, fadedThrowShape, oldShape, oldFadedShape;
-
- // Get shapes
- GetPictureItem((*aJuggle)->throwsPict, shapeIndex, &throwShape, nil, nil, nil);
- GetPictureItem((*aJuggle)->fadedThrowsPict, shapeIndex, &fadedThrowShape, nil, nil, nil);
-
- // Copy the shapes
- oldShape = GXCopyToShape(nil, throwShape);
- NilShapeReturn(oldShape);
- oldFadedShape = GXCopyToShape(nil, fadedThrowShape);
- NilShapeReturn(oldFadedShape);
-
- // Set new line, erase, and draw
- GXSetLine(throwShape, newLine);
- GXSetLine(fadedThrowShape, newLine);
- GXDrawShape(oldShape);
- GXDrawShape(throwShape);
- GXDrawShape(oldFadedShape);
- GXDrawShape(fadedThrowShape);
-
- // Clean up
- GXDisposeShape(oldShape);
- GXDisposeShape(oldFadedShape);
- }
-
-
- // Empty out the throws picture and rebuild it from the connections data
- void RebuildThrowsPict(JuggleHandle aJuggle)
- {
- gxShape throwsPict, fadedThrowsPict;
- Fixed handRadius;
- short timeCount, jugglerCount;
-
- handRadius = kHandRadius;
- throwsPict = (*aJuggle)->throwsPict;
- fadedThrowsPict = (*aJuggle)->fadedThrowsPict;
-
- // Remove all shapes from the picts
- GXSetPictureParts( throwsPict, // the picture
- 1, // first item to remove
- gxSelectToEnd, // remove all the way to the end
- 0, // nothing being inserted
- nil, // no shapes, styles, inks, or transforms
- nil,
- nil,
- nil );
- GXSetPictureParts( fadedThrowsPict, 1, gxSelectToEnd, 0, nil, nil, nil, nil);
-
- // build it back up again
- for(timeCount = 1; timeCount <= (*aJuggle)->numCounts; timeCount++)
- {
- for(jugglerCount = 1; jugglerCount <= (*aJuggle)->numJugglers; jugglerCount++)
- {
- HandPtr hand = GetIndexedHand(aJuggle, timeCount, jugglerCount, false);
- if(hand != nil && hand->sink.time > 0) // if there's a sink, make a throw for it
- {
- gxLine aLine;
- HandLoc aLoc;
-
- // Set the first point
- aLoc.time = timeCount;
- aLoc.juggler = jugglerCount;
- HandLocToPoint(aJuggle, &aLoc, &aLine.first);
- aLine.first.x += handRadius; // move off the hand
-
- // Set the last point. If the throw wraps around, set the
- // last point off the right edge
- if(hand->sink.time > timeCount)
- aLoc.time = hand->sink.time;
- else
- aLoc.time = hand->sink.time + (*aJuggle)->numCounts;
- aLoc.juggler = hand->sink.juggler;
- HandLocToPoint(aJuggle, &aLoc, &aLine.last);
- aLine.last.x -= handRadius; // move off the hand
-
- // Add the new throw shape
- AddNewThrowShape(aJuggle, &aLine, false);
- }
- }
- }
- }
-
- void MoveJugglerInPict(JuggleHandle aJuggle, short fromRow, short toRow)
- {
- gxShape jugglersPict, movedShape, theShapes[kMaxJugglers];
- short numJugglers, rowDistance, increment, index;
-
- jugglersPict = (*aJuggle)->jugglersPict;
-
- // Get the shapes
- numJugglers = GXGetPicture(jugglersPict, theShapes, nil, nil, nil);
-
- // Sanity Check
- /* if(numJugglers != (*aJuggle)->numJugglers)
- {
- SysBeep(10);
- return;
- }
- */
- // see how far we moved
- rowDistance = toRow - fromRow;
-
- index = fromRow - 1;
- if(rowDistance < 0)
- {
- // moving up
- increment = -1;
- rowDistance = -rowDistance;
- }
- else
- {
- // moving down
- increment = 1;
- }
-
- // Save off a copy of the moved shape, and move its screen position
- movedShape = theShapes[fromRow - 1];
- GXMoveShape(movedShape, 0, (*aJuggle)->gridPt.y * increment * rowDistance);
-
- // Move the block of shapes between the from and to rows
- while(rowDistance-- > 0)
- {
- // move its position in the picture
- theShapes[index] = theShapes[index + increment];
-
- // Move its position on screen
- GXMoveShape(theShapes[index], 0, -((*aJuggle)->gridPt.y * increment));
-
- // next shape
- index += increment;
- }
-
- // insert moved juggler in destination row
- theShapes[toRow - 1] = movedShape;
-
- // Restore picture
- GXSetPicture(jugglersPict, numJugglers, theShapes, nil, nil, nil);
- }
-
- void SwitchJugglerHands(JuggleHandle aJuggle, short jugglerNum)
- {
- gxShape firstHand, oldJuggler, newJuggler;
- unsigned char handText[2] = "R";
- short rowNum;
-
- rowNum = JugglerToRow(aJuggle, jugglerNum);
-
- // Get the juggler
- GetPictureItem((*aJuggle)->jugglersPict, rowNum, &oldJuggler, nil, nil, nil);
-
- // Get the text in the first hand
- GetPictureItem(oldJuggler, 2, &firstHand, nil, nil, nil);
- GXGetText(firstHand, nil, handText, nil);
-
- // Make the right replacement, position it, and replace it
- newJuggler = MakeJugglerShape(aJuggle, (handText[0] != 'R'), jugglerNum);
- if(rowNum > 1) // prevents warning: geometry_unnaffected
- GXMoveShape(newJuggler, 0, (*aJuggle)->gridPt.y * (rowNum - 1));
- SetPictureItem((*aJuggle)->jugglersPict, rowNum, newJuggler, nil, nil, nil);
- GXDisposeShape(newJuggler);
- }
-
- void ChangeJugglerLabel(JuggleHandle aJuggle, short juggler, short newId)
- {
- gxShape jugglerShape, labelShape;
- short row;
-
- row = JugglerToRow(aJuggle, juggler);
- GetPictureItem((*aJuggle)->jugglersPict, row, &jugglerShape, nil, nil, nil);
- if(jugglerShape != nil)
- {
- // get label
- GetPictureItem(jugglerShape, 1, &labelShape, nil, nil, nil);
- if(labelShape != nil)
- {
- char numberText[50], labelText[50] = "Juggler ";
- long length;
-
- // Make the new label string
- NumToString((long)newId, (StringPtr)numberText);
- p2c((StringPtr)numberText);
- ccat(labelText, numberText);
- length = clen(labelText);
-
- // Set it
- GXSetText(labelShape, length, (unsigned char*)labelText, nil);
- }
- }
- }
-
- // Modelled after SetDeepShapeTransform in the transform library
- void SetDeepShapeInk(gxShape sh, gxInk ink)
- {
- if (GXGetShapeType(sh) == gxPictureType) {
- register short count = GXGetPicture(sh, nil, nil, nil, nil);
- gxShape itemShape;
- gxInk itemInk;
-
- while (count) {
- GXGetPictureParts(sh, count, 1, &itemShape, nil, &itemInk, nil);
- if (itemInk) {
- gxStyle itemStyle;
- gxTransform itemXform;
-
- GXGetPictureParts(sh, count, 1, &itemShape, &itemStyle, &itemInk, &itemXform);
- GXSetPictureParts(sh, count, 1, 1, &itemShape, &itemStyle, &ink, &itemXform);
- }
- SetDeepShapeInk(itemShape, ink);
- count--;
- }
- }
- GXSetShapeInk(sh, ink);
- }
-
- RgnHandle GetShapeBoundsRgn(gxShape shape)
- {
- gxRectangle bounds;
- RgnHandle rgn;
-
- GXGetShapeLocalBounds(shape, &bounds);
- rgn = NewRgn();
- SetRectRgn(rgn, FixedRound(bounds.left), FixedRound(bounds.top),
- FixedRound(bounds.right), FixedRound(bounds.bottom));
- return rgn;
- }
-
- Rect *GetShapeBoundsQDRect(gxShape shape, Rect *rect)
- {
- gxRectangle bounds;
-
- GXGetShapeLocalBounds(shape, &bounds);
- return FixedRectToShort(&bounds, rect);
- }
-
- Point GetQDWindowOrigin(WindowPtr window)
- {
- gxViewPort docPort;
- gxPoint theGXPt;
- Point theQDPt;
-
- theQDPt.h = theQDPt.v = 0;
- LocalToGlobal(&theQDPt);
- docPort = GetWindowGXPort(window);
- GXConvertQDPoint(&theQDPt, docPort, &theGXPt);
- FixedPointToShort(&theGXPt, &theQDPt);
- return theQDPt;
- }
-
- void SetShapeMainPort(JuggleHandle aJuggle, gxShape shape)
- {
- gxViewPort aPort;
-
- aPort = (*aJuggle)->docPort;
- SetDeepShapeViewPorts(shape, 1, &aPort);
- }
-
- void SetShapeFadePorts(JuggleHandle aJuggle, gxShape shape)
- {
- gxViewPort fadePorts[2];
-
- fadePorts[0] = (*aJuggle)->beforePort;
- fadePorts[1] = (*aJuggle)->afterPort;
- SetDeepShapeViewPorts(shape, 2, fadePorts);
- }
-
- void SetInkBlendMode(gxInk theInk, short percent)
- {
- gxTransferMode theMode;
-
- GXGetInkTransfer(theInk, &theMode);
-
- // Straight out of IM: Objects p. 5-44
- theMode.flags = gxSingleComponentTransfer;
- theMode.component[0].mode = gxBlendMode;
-
- theMode.component[0].flags = 0;
- theMode.component[0].sourceMinimum = 0;
- theMode.component[0].sourceMaximum = gxColorValue1;
- theMode.component[0].deviceMinimum = 0;
- theMode.component[0].deviceMaximum = gxColorValue1;
-
- theMode.component[0].clampMinimum = 0;
- theMode.component[0].clampMaximum = gxColorValue1;
- theMode.component[0].operand =
- (((unsigned long)gxColorValue1) * percent) / 100;
-
- GXSetInkTransfer(theInk, &theMode);
- }
-
- void ResetJuggleContentSize(JuggleHandle aJuggle)
- {
- short counts, jugglers;
- Point shortGrid;
-
- FixedPointToShort(&(*aJuggle)->gridPt, &shortGrid);
- counts = (*aJuggle)->numCounts;
- jugglers = (*aJuggle)->numJugglers;
- (*aJuggle)->contentSize.h = ((2 * counts) + 1) * shortGrid.h + 1;
- (*aJuggle)->contentSize.v = jugglers * shortGrid.v;
- }
-
- // Get the picture that contains the throws
- gxShape GetDocThrowsPict(WindowPtr wind)
- {
- return (*GetWindowJuggle(wind))->throwsPict;
- }
-
- // Get the picture that contains the faded throws
- gxShape GetDocFadedThrowsPict(WindowPtr wind)
- {
- return (*GetWindowJuggle(wind))->fadedThrowsPict;
- }
-